package drongo.model.values
{
	import drongo.model.core.BaseValue;
	import drongo.model.core.IProperty;
	import drongo.model.core.ISerialization;
	import drongo.model.core.IValue;
	import drongo.model.events.ModelEvent;
	import drongo.model.propertys.ArrayProperty;
	import drongo.model.propertys.CollectionProperty;
	import drongo.model.propertys.NumberProperty;
	import drongo.model.propertys.StringProperty;
	
	import flash.utils.Dictionary;
	
	/**
	 * 集合数据
	 */
	public class CollectionValue extends BaseValue implements ISerialization
	{
		private var valueList:Array;
		public function CollectionValue()
		{
			super();
			this.value=new Dictionary();
			this.valueList=[];
		}
		
		
		private function ChildValueChanged(e:ModelEvent):void{
			var target:IValue=e.target as IValue;
			if(this.hasEventListener(ModelEvent.CHILD_VALUE_CHANGED)){
				this.dispatchEvent(ModelEvent.Create(ModelEvent.CHILD_VALUE_CHANGED,target));
			}
		}
		
		private function ChildChildValueChanged(e:ModelEvent):void{
			var target:IValue=e.target as IValue;
			if(this.hasEventListener(ModelEvent.CHILD_VALUE_CHANGED)){
				this.dispatchEvent(ModelEvent.Create(ModelEvent.CHILD_VALUE_CHANGED,target));
			}
		}
		
		public function Add(value:IProperty):void{
				if(this.dic[value.GetKey()]!=null){
					throw new Error("重复添加相同KEY的属性！");
				}
				this.dic[value.GetKey()]=value;
				this.valueList.push(value);
				if(this.hasEventListener(ModelEvent.ADD_CHILD)){
					this.dispatchEvent(ModelEvent.Create(ModelEvent.ADD_CHILD,value));
				}
				value.addEventListener(ModelEvent.VALUE_CHANGED,this.ChildValueChanged);
				value.addEventListener(ModelEvent.CHILD_VALUE_CHANGED,this.ChildChildValueChanged);
		}
		
		public function Remove(value:IProperty):void{
			this.RemoveByKey(value.GetKey());
		}
		
		public function RemoveByKey(key:String):void{
			if(this.dic[key]==null){
				throw new Error("要删除的属性不在集合内！");
			}
			var data:IValue=this.dic[key];
			delete this.dic[key];
			var index:int=this.valueList.indexOf(data);
			this.valueList.splice(index,1);
			if(this.hasEventListener(ModelEvent.REMOVE_CHILD)){
				this.dispatchEvent(ModelEvent.Create(ModelEvent.REMOVE_CHILD,data));
			}
			data.removeEventListener(ModelEvent.VALUE_CHANGED,this.ChildValueChanged);
			data.removeEventListener(ModelEvent.CHILD_VALUE_CHANGED,this.ChildChildValueChanged);
		}
		
		/**
		 * 修改
		 */
		public function Update(key:String,value:*):void{
			if(this.dic[key]==null){
				throw new Error("要更新的属性不存在！"+key);
			}
			var property:IProperty=this.dic[key];
			property.SetValue(value);
		}
		
		/**
		 * 一次改变多个属性
		 */
		public function MultUpdate(keys:Array,values:Array):void{
			if(keys==null||values==null){
				throw new Error("Keys和values不能为空！");
			}
			if(keys.length!=values.length){
				throw new Error("keys.length!=values.length");
			}
			var key:String;
			var value:*;
			for (var i:int = 0; i < keys.length; i++) 
			{
				key=keys[i];
				value=values[i];
				Update(key,value);
			}
		}
		
		/**
		 * 查询
		 */
		public function Get(key:String):IProperty{
			return this.dic[key];
		}
		
		override public function Equality(value:IValue):Boolean{
			if(value is CollectionValue){
				var collValue:CollectionValue=value as CollectionValue;
				if(this.list.length!=collValue.list.length){
					return false;
				}
				var a:IProperty;
				var b:IProperty;
				for (var i:int = 0; i < this.list.length; i++) 
				{
					a=this.list[i];
					b=collValue.list[i];
					if(a.Equality(b)!=false){
						return false;
					}
				}
				return true;
			}
			return false;
		}
		
		public function get dic():Dictionary{
			return this.value as Dictionary;
		}
		
		/**
		 * 列表
		 */
		public function get list():Array{
			return this.valueList;
		}
		
		public function Clear():void
		{
			var item:IProperty;
			for (var pKey:String in this.value) 
			{
				item=this.value[pKey];
				this.Remove(item);
			}
			this.valueList.length=0;
		}
		
		override public function Decode(type:uint, data:*):void
		{
			if(type==0){
				var item:*;
				var property:IProperty;
				for(var pKey:String in data) 
				{
					item=data[pKey];
					if(item is Array){
						property=new ArrayProperty(pKey);
					}else{
						//字符串
						if(item is String){
							property=new StringProperty(pKey);
						}else{
							var numValue:Number=Number(item);
							//非数字
							if(isNaN(numValue)){
								property=new CollectionProperty(pKey);
							}else{
								property=new NumberProperty(pKey);
							}
						}	
					}
					property.Decode(type,item);
					this.Add(property);
				}
			}
		}
		
		override public function Encode(type:uint, data:*=null):*
		{
			if(type==0){
				var result:Object={};
				var item:IProperty;
				for (var pKey:String in this.value) 
				{
					item=this.value[pKey];
					result[pKey]=item.Encode(type);
				}
				return result;
			}
			return null;
		}
	}
}